o3djs.require('o3djs.util');
o3djs.require('o3djs.math');
o3djs.require('o3djs.rendergraph');
o3djs.require('o3djs.material');
o3djs.require('o3djs.picking');
o3djs.require('o3djs.pack');
o3djs.require('o3djs.debug');
o3djs.require('o3djs.loader');
o3djs.require('o3djs.primitives');

/*
o3djs.require('script.listen');
o3djs.require('script.Superfluous');
o3djs.require('script.createCode');
o3djs.require('script.menu');
o3djs.require('script.dialog');
o3djs.require('script.dialog_kids');
o3djs.require('script.dialog_wov');
*/
var PI = Math.PI;

//-----------------------------------------------------------------全局对象
var model_id;
//------------------------------------
var o3dElement;
var cubeClient;
var menuClient;
var cubeO3d;
var cubePack;
var o3dMath;
//
var viewInfo;
var menuViewInfo;
var backViewInfo;
//
var cubeMass = new Array;
var menuMass = new Array;
var menuMassData = new Array;
var backImage = new Array;//背景大对象
var shape = new Array;//存储shape的原始体
//--------------------------------------------------------------------视觉投影对象
var eyeMoveDelta = new Array;//视角角度增量值的缓存

//第一项是向量与XY平面的夹角，第二项是与XZ平面的夹角,第三项代表R值，后面三项是视觉中心的绝对坐标。
var eyeOri = [3*PI/4,PI/4,40,0,0,0];
//存储摄像机当前位置
var eyePosi = new Array;
//存储摄像机当前角度a、b，第一项是向量与XY平面的夹角，第二项是与XZ平面的夹角
var eyeAngle = new Array;
//存储摄像机当前距离视觉中心的距离R
var eyeR;
//存储当前视觉中心的绝对坐标值
var viewCenter = new Array;

var eyeTarAmong;
//--------------------------------------------------------------------有关互动操作的变量
var undoNumber = new Array;
var zoomFactor = 1.7;
var moveFactor = 0.005;
var factor = 0;//闪烁时间函数的变量
var factorSin;

var moveTime;//通用的动作时间函数
var acceleraTime;//计算速度的时间函数
var frameMoveTime = new Array;//对话框的移动函数数组
var frameAlphaTime = new Array;//对话框改变透明度的时间对象，是个数组。

var mouseButton = new Array;//全局的开关
var mouseMode = true;//打开鼠标是否可用的开关，在观察模式下的控制
var mouseCursor = "DEFAULT";//控制鼠标的光标状态，存储字符串
var mouseAmong = "DEFAULT";
var mouseCursorStatus; //


var customizeCursor; //笔刷光标


var cubeDragging = false;
//--------------------------------------------------------------------存储全部的cube
var defultValue = defultValue||{};
	defultValue.red = 1;
	defultValue.green = 1;
	defultValue.blue = 1;
	defultValue.alpha = 1;
	
	defultValue.x = 0;
	defultValue.y = 0;
	defultValue.z = 0;
	
//画笔相关--------------------------------------------------------------------
var colorOftenUse = new Array; //存储经常使用颜色的数组。


//---------------------------------------------------------------------------------
var cubeFinished = false;
var cubeSelect = new Array ;
var cubeSelectNow = new Array;// 存储选中cube的信息，[0]为mass的序号[1]是碰撞信息[2]是队选中对象的引用[3]选中的面
var frameActiveNow = new Array;//对话框激活数组
	frameActiveNow.dragFrame = new Array;//存储左键点中的frame，可以进行拖动操作。
var menuSelect = new Array;
var moveArrow;//移动提示的箭头
var growthArrow;//生成提示的箭头
var cubeCoordArray = new Array;// 存储所有cube的坐标值，比较防止cube重叠生成。

var growthBounding;//拖拽生成平面
var touchPicked;//只存储被选择的pick对像

var deltaCubesKey = new Array; //流水操作生成cube的关键数目记录
var freezeSelectNow = new Array;//流水操作中用来转存生成前的 cube阵列。
var freezeSelectMatrix = new Array;
var drawCubePlan;
	
var backMaterial;
var menuMaterial;
var zBuffer = 3000;//Z值缓冲，使用后应自加1,最高是4000
var materialUrls = [
	'ishader/texture-colormult.shader'
	];
var textures = new Array;
var textureUrls = [
					"ipic/menu_blank.png",
					"ipic/menu_c.png",
					"ipic/menu_colorPen.png",
					"ipic/menu_ctrl_a.png",
					"ipic/menu_ctrl_g.png",
					"ipic/menu_ctrl_s.png",
					"ipic/menu_ctrl_z.png",
					"ipic/menu_del.png",
					"ipic/menu_down.png",
					"ipic/menu_e.png",
					"ipic/menu_esc.png",
					"ipic/menu_g.png",
					"ipic/menu_i.png",
					"ipic/menu_left.png",
					"ipic/menu_m.png",
					"ipic/menu_r.png",
					"ipic/menu_review.png",
					"ipic/menu_right.png",
					"ipic/menu_up.png",
					"ipic/menu_f.png",
					"ipic/colorLine_cursor.png",
					"ipic/colorTBg.png",
					//"ipic/chooseLibrary.png",
					"ipic/colorLibrary.png",
					"ipic/comparisonBg.png",
					"ipic/switchButton.png",
					"ipic/switchButtonOn.png",
					"ipic/changeButton.png",				
					"ipic/changeButtonOn.png",
					"ipic/emptyButton.png",	
					"ipic/emptyButtonOn.png",
					"ipic/customizeButton.png",	
					"ipic/customizeButtonOn.png",
					"ipic/joinButton.png",	
					"ipic/joinButtonOn.png",
					"ipic/deleteButton.png",	
					"ipic/deleteButtonOn.png",
					"ipic/dropperButton.png",	
					"ipic/dropperButtonOn.png",
					"ipic/setColor_cover.png",
					"ipic/setColor_title.png",
					"ipic/setColor_rgb_cursor.png",
					"ipic/setColor_pure_cursor.png",
					"ipic/setColor_line_cursor.png",
					"ipic/button_white.png",
					"ipic/button_red.png",
					"ipic/button_blue.png",
					"ipic/tips_bg.png",
					"ipic/button_closeX_red.png",
					"ipic/button_closeX_white.png",
					"ipic/button_ok_blue.png",
					"ipic/button_ok_white.png",
					
					"ipic/librarySelect_bg.png",
					"ipic/librarySelect_colorBg.png",
					"ipic/librarySelect_colorFrame.png",
					"ipic/librarySelect_cursor.png",
					"ipic/librarySelect_del_red.png",
					"ipic/librarySelect_del_white.png",
					
					"ipic/librarySelect_left_blue.png",
					"ipic/librarySelect_left_gray.png",
					"ipic/librarySelect_right_blue.png",
					"ipic/librarySelect_right_gray.png",
					
					"ipic/librarySelect_leftCover.png",
					"ipic/librarySelect_rightCover.png",
					
					"ipic/colorMark.png",
					
					"ipic/brush.png"
					
					];

window.onunload = uninit;

function init(){
	o3djs.util.makeClients(initCreateCube);
	}
	
function uninit() {
    if (cubeClient) {
   		cubeClient.cleanup();
  		}
	}

function initCreateCube(clientElements){
	o3dElement = clientElements[0];
	cubeClient = o3dElement.client;
	cubeO3d = o3dElement.o3d;
	o3dMath = o3djs.math;
	cubePack = cubeClient.createPack(); 
	
	cubeMass.transform = cubePack.createObject("Transform");
	cubeMass.transform.parent = cubeClient.root;
	//给每个MAss 都具有一个本地的x,y,z;加快执行maaa操作的执行
	cubeMass.x = 0;
	cubeMass.y = 0;
	cubeMass.z = 0;
	cubeMass.localX = 0;
	cubeMass.localY = 0;
	cubeMass.localZ = 0;
	cubeSelect.push(cubeMass);
	
	menuMass.transform = cubePack.createObject("Transform");
	menuMass.transform.parent = cubeClient.root;
	backImage.transform = cubePack.createObject("Transform");
	backImage.transform.parent = cubeClient.root;

	initEye();
	initViewInfo();	
	initTexture();//进入一个加载贴图的等待函数。
	
	shape[2] = new creator.framePlan();
	shape[1] = new creator.frameLine(1,1,1,1);
	shape[0] = new creator.oriCube();
	shape[4] = new creator.frameLine(0,0,0,1);
	
	moveArrow = new creator.coupleArrow(1,0.2,0.2,1);
	growthArrow = new creator.growthArrow(1,0.2,0.2,1);
	

	mouseButton["alphaTime"] = true;
	flashFramesIf();
	}
	
function initTexture(){
	var loader = o3djs.loader.createLoader(afterTextureLoaded);
	var textureLinkName;
	for(var n=0;n < textureUrls.length;n++){
		textureLinkName = textureUrls[n];
		textureLinkName = cutUrlToSingle(textureLinkName);
		textures[textureLinkName] = textureUrls[n];
		loadTexture(loader,textureLinkName);
		}
	loader.finish();
	}

function loadTexture(loader,urlObj){
	loader.loadTexture(cubePack, textures[urlObj], function(texture, exception) {
					   if (exception) {
					   alert(exception);
					   }
					   else {
					   textures[urlObj] = texture;}});
	}
	
//图像加载完成后进行的事情，有关图像贴图的都应该写在这里面---------------------------------
function afterTextureLoaded(){
	//初始化菜单系统------------------------------------------------
	menu.init();
	//创建对话框构造对象，初始化调色板
	var defultCreator = new dialog.basicCreator();
	dialog.setColor = dialog.create_SetColor(defultCreator,[defultValue.red,
															defultValue.green,
															defultValue.blue,
															defultValue.alpha]);
	dialog.setColor.changeFrameAlpha([0]);
	dialog.tips = dialog.create_ATips(defultCreator,"这是什么？",800);
	
	dialog.setColor.changeZ([-1000]);
	//初始化背景----------------------------------------------------------
	backGround.init();
	//创建第一个方块
	creator.insertCubeOri();
	//一切都加载完成后可以初始化监听事件----------------------------
	initEvent();
	//var bbb = cubeClient.toDataURL("image/png");
	dialog.tips.showBy("欢迎来到自由方块世界！初次使用，场景中间已经预先创建了一个原始的方块,你需要它来逐渐创建出你自己的方块造型。先点击它试试^_^。",500);
	cubeFinished = true;
	if(model_id){
		loadModel(model_id);
		}
	
	
	
	}
	
	
function cutUrlToSingle(url){
	var subNum = url.indexOf("/");
	var subUrl = url.slice(subNum + 1);
	subNum = subUrl.indexOf("/");
	if(subNum == -1){
		subNum = subUrl.indexOf(".");
		subUrl = subUrl.slice(0,subNum);
		return  subUrl;
		}
		else{
			return cutUrlToSingle(subUrl);
			}
	
	}	

//闪烁函数--------------------------------------------------------------------------
function flashFramesIf(){
	var flashCheck = setInterval(function(){flashFrames()},50);
	var reCheckAlpha = setInterval(function(){flashFramesTime()},50);
	}
	
function flashFrames(){
	factor +=0.2;
	if(mouseButton["alphaTime"]){
		factorSin = (Math.cos(factor)+1)/2;
		}
		else{
			factorSin = 0.5;
			}
	}
	
function flashFramesTime(){
	if (cubeSelectNow[0]){
		if(moveArrow.visible){
			moveArrow.arrowTransform_0_Move.identity();
			moveArrow.arrowTransform_0_Move.translate(0,(Math.cos(factor)+1)/10,0);
			moveArrow.arrowTransform_1_Move.identity();
			moveArrow.arrowTransform_1_Move.translate(0,(Math.cos(factor)+1)/10,0);
			}
		else if(growthArrow.visible){
			growthArrow.transform_0.identity();
			growthArrow.transform_0.translate(0,(Math.cos(factor)+1)/7,0);
			if(factorSin>0.8){
				growthArrow.displayCube();
				}
			else{
				growthArrow.clearCube();
				}
			}
		for(var n=0;n < cubeSelectNow.length;n++){
			if(cubeSelectNow[n][2][0]){
				flashFramesNesting(cubeSelectNow[n][2]);
				}
				else{
					 if(!cubeSelectNow[n][2].wireFrame){
						creator.addFrames(shape[1].frameShape,shape[2].planShape,
														1,1,1,1,
														cubeSelectNow[n][2],
														cubeSelectNow[n][3],
														1);
					 }
					 else{
						 for(var nDir=0;nDir < 6;nDir++){
							 if(cubeSelectNow[n][3][nDir]){
						 cubeSelectNow[n][2].wireFrame.transformPlanArray[nDir].getParam("diffuse").value = [
															 1,
															 1,
															 1,
															 factorSin*cubeSelectNow[n][2].alpha
															 ];
								 }
							 }
						}
					}
			}
			}
	}
	
function flashFramesNesting(mass){
	for(var n=0;n < mass.length;n++){
		if(mass[n][0]){
			flashFramesNesting(mass[n]);
			}
			else{
				 if(!mass[n].wireFrame){
					creator.addFrames(shape[4].frameShape,shape[2].planShape,
													1,1,1,1,
													mass[n],
													[],
													1);
					 }
				
			}		
		}
	}
//初始化基本函数-------------------------------------------------------------------------------------
function initEye(){
	eyeAngle[0] = eyeOri[0];
	eyeAngle[1] = eyeOri[1];
	eyeR = eyeOri[2];
	viewCenter[0] = eyeOri[3];
	viewCenter[1] = eyeOri[4];
	viewCenter[2] = eyeOri[5];
	eyePosi[2] = eyeR*Math.cos(eyeAngle[1])*Math.sin(eyeAngle[0]) + viewCenter[2];
	eyePosi[1] = eyeR*Math.sin(eyeAngle[1]) + viewCenter[1];
	eyePosi[0] = eyeR*Math.cos(eyeAngle[1])*Math.cos(eyeAngle[0]) + viewCenter[0];
	}
	
function initViewInfo(){
	viewInfo = o3djs.rendergraph.createBasicView(cubePack,
												 cubeMass.transform,
												 cubeClient.renderGraphRoot);
	viewInfo.drawContext.projection = o3dMath.matrix4.perspective(o3dMath.degToRad(30),
																	  cubeClient.width/cubeClient.height,
																	  1,
																	  2000);
	viewInfo.drawContext.view = o3dMath.matrix4.lookAt(eyePosi,
														viewCenter,
														[0,1,0]);
	//viewInfo.clearBuffer.clearColor = [1,1,1,0]
	viewInfo.clearBuffer.clearColorFlag = false;
	//下面是鼠标菜单的图形
	menuViewInfo = o3djs.rendergraph.createBasicView(cubePack,
													 menuMass.transform,
													 cubeClient.renderGraphRoot);
	menuViewInfo.drawContext.projection = o3dMath.matrix4.orthographic(0.5,
																	   cubeClient.width + 0.5,
																	   cubeClient.height + 0.5,
																	   0.5,
																	   -10000,
																	   100);
	menuViewInfo.drawContext.view = o3dMath.matrix4.lookAt( [0, 0, 1],
															[0, 0, 0],
															[0, 1, 0]);
	
	menuViewInfo.root.priority = viewInfo.root.priority + 1;
	menuViewInfo.clearBuffer.clearColorFlag = false;
	menuViewInfo.zOrderedState.getStateParam("CullMode").value = cubeO3d.State.CULL_NONE;
	menuViewInfo.zOrderedState.getStateParam("ZWriteEnable").value = false;
	//操作背景的视图对象
	backViewInfo = o3djs.rendergraph.createBasicView(cubePack,
													 backImage.transform,
													 cubeClient.renderGraphRoot);
	backViewInfo.drawContext.projection = o3dMath.matrix4.orthographic(0.5,
																	   cubeClient.width + 0.5,
																	   cubeClient.height + 0.5,
																	   0.5,
																	   100,
																	   1000);
	backViewInfo.drawContext.view = o3dMath.matrix4.lookAt( [0, 0, 1],
															[0, 0, 0],
															[0, 1, 0]);
	
	backViewInfo.root.priority = viewInfo.root.priority - 1;
	backViewInfo.clearBuffer.clearColorFlag = false;
	backViewInfo.zOrderedState.getStateParam("CullMode").value = cubeO3d.State.CULL_NONE;
	backViewInfo.zOrderedState.getStateParam("ZWriteEnable").value = false;
	}

function initEvent(){
	o3djs.event.addEventListener(o3dElement,"mousedown",listen.startDragging);
	o3djs.event.addEventListener(o3dElement,"mousemove",listen.drag);
	o3djs.event.addEventListener(o3dElement,"mouseup",listen.stopDragging);
	o3djs.event.addEventListener(o3dElement,"wheel",listen.scrollCubes);
	o3djs.event.addEventListener(o3dElement,'keydown',listen.keyDown);
	//o3djs.event.addEventListener(o3dElement,'keyup',listen.judgeKeyUp);
	o3djs.event.addEventListener(o3dElement,'dblclick',listen.editMass);
	}
	
	
//一系列附加函数----------------------------------------------------------------------
function sortNumber(a,b){
	return a[0] - b[0];
	}
	
function sortFall(a,b){
    return a - b;	
	}
	
	
function compareDir(a,b){
	if (a[0]==b[0] && 
		a[1]==b[1] &&
		a[2]==b[2] &&
		a[3]==b[3] &&
		a[4]==b[4] &&
		a[5]==b[5]){
		return true;
		}
	return false;
	}

if(!Number.prototype.toFixed){
	Number.prototype.toFixed = function(n){  
									  return   Math.round(Math.Number(this)*Math.pow(10,n))/Math.pow(10,n);
									  }
	}   

String.prototype.longFixed = function(num){
	var returnString = this;
	returnString = returnString.slice(-num);
		for(var n=0;n < num-this.length;n++){
			returnString = "0" + returnString;
			}
	return returnString;
	}

function resizeClient(){
	viewInfo.drawContext.projection = o3dMath.matrix4.perspective(o3dMath.degToRad(30),
																	  cubeClient.width/cubeClient.height,
																	  1,
																	  2000);
	
	menuViewInfo.drawContext.projection = o3dMath.matrix4.orthographic(0.5,
																	   cubeClient.width + 0.5,
																	   cubeClient.height + 0.5,
																	   0.5,
																	   -10000,
																	   100);
	
	backViewInfo.drawContext.projection = o3dMath.matrix4.orthographic(0.5,
																	   cubeClient.width + 0.5,
																	   cubeClient.height + 0.5,
																	   0.5,
																	   100,
																	   1000);
	}


function createCubeCoordArray(createX,createY){
	if (!cubeCoordArray[createX]){
		cubeCoordArray[createX] = new Array;
		if(!cubeCoordArray[createX][createY]){
			cubeCoordArray[createX][createY] = new Array;
			}
		}else if(!cubeCoordArray[createX][createY]){
			cubeCoordArray[createX][createY] = new Array;
			}
	} 


frameActiveNow.sortUp = function(num){
	var newTop = this[num];
	for(var nActive=num;nActive < frameActiveNow.length-1;nActive++){
		this[nActive] = this[nActive+1];
		}
	this[nActive] = newTop;
	for(var n=0;n < this.length;n++){
		for(var i=0;i < this[n].length;i++){
			this[n][i].changeZ([n*300+i*30]);
			}
		}
	}
	
frameActiveNow.sortDown = function(num){
	var newTop = this[num];
	for(var nActive=num;nActive>0;nActive++){
		this[nActive] = this[nActive-1];
		}
	this[0] = newTop;
	for(var n=0;n < this.length;n++){
		for(var i=0;i < this[n].length;i++){
			this[n][i].changeZ([n*300+i*30]);
			}
		}
	}
